package site.tuluan.sp4j.common.core.component.shiro.realm;

import com.google.common.collect.Sets;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.BearerToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import site.tuluan.sp4j.common.core.component.token.TokenService;
import site.tuluan.sp4j.common.core.domain.LoginUser;
import site.tuluan.sp4j.common.core.service.permission.IPermissionService;
import site.tuluan.sp4j.common.core.service.role.IRoleService;
import site.tuluan.sp4j.common.utils.security.SecurityUtils;
import site.tuluan.sp4j.common.utils.spring.SpringUtils;

import javax.annotation.Resource;

/**
 * 自定义realm
 *
 * @author tuluan
 */
public class Sp4jRealm extends AuthorizingRealm {

    private static final class TokenServiceHolder {
        private static final TokenService tokenService = SpringUtils.getBean(TokenService.class);
    }

    private TokenService getTokenService() {
        return TokenServiceHolder.tokenService;
    }

    @Resource
    private IRoleService roleService;

    @Resource
    private IPermissionService permissionService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof BearerToken;
    }

    /**
     * 获取授权信息
     * @param principalCollection 主体集合
     * @return 授权信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();

        String userId = SecurityUtils.getCurrentSysUser().getId();

        // 超级管理员有所有权限
        if (SecurityUtils.isSuperAdmin(userId)) {
            authInfo.setRoles(Sets.newHashSet("admin"));
            authInfo.setStringPermissions(Sets.newHashSet("*:*:*"));
        } else {
            // 拥有的角色集
            authInfo.setRoles(roleService.getRoleByUserId(userId));
            // 拥有的功能权限集
            authInfo.setStringPermissions(permissionService.getPermissionByUserId(userId));
        }


        return authInfo;
    }

    /**
     * 获取身份验证信息
     * @param authenticationToken 身份验证令牌
     * @return 身份验证信息
     * @throws AuthenticationException 身份验证异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String)authenticationToken.getCredentials();
        LoginUser loginUser;
        try {
            loginUser = getTokenService().getLoginUser(token);
        } catch (Exception e) {
            throw new AuthenticationException(e.getMessage(), e);
        }

        if (loginUser == null) {
            throw new AuthenticationException("用户未登录");
        }

        if (!getTokenService().verifyToken(token, loginUser)) {
            throw new AuthenticationException("token验证失败");
        }

        return new SimpleAuthenticationInfo(loginUser, loginUser.getToken(), getName());
    }
}
